﻿using Eps.Ai.Common;
using InfonavaEye.common;
using InfonavaEye.components;
using InfonavaEye.Handler;
using Newtonsoft.Json.Linq;
using Sylan.Common.Util;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Media;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Timers;
using System.Windows.Forms;

namespace InfonavaEye.handler
{
    public class PLCHandler
    {
        private UpperComputerUtil upper;

        public Action PLCInitCompleteDelegate;

        public Action triggerCaptureDelegate;

        public Action moveToOriginCompleteDelegate;

        //心跳监测
        private bool heartBeatEnabled = false;
        System.Timers.Timer heartBeatTimer = null;
        public event Action<bool> heartBeatDelegate;

        bool isConnected = false;

        /// <summary>
        /// z轴回到了圆点，通知UI
        /// </summary>
        /// <param name="imagePath"></param>
        public delegate void Z2ZeroDelegate();
        public event Z2ZeroDelegate z2ZeroDelegate;

        private static readonly PLCHandler instance = new PLCHandler();

        static PLCHandler() { }
        private PLCHandler() { }
        public static PLCHandler Instance
        {
            get
            {
                return instance;
            }
        }

        public void StartPLC()
        {
            if (isConnected) {
                if (this.PLCInitCompleteDelegate != null)
                {
                    this.PLCInitCompleteDelegate.Invoke();
                }
                return;
            }

            ThreadHelper.ExcuteThreadTask(() =>
            {
                Connect();
            }, 50);
        }

        public void ClosePLC()
        {
            try
            {
                if (upper != null)
                {
                    upper.CloseSerialPort();
                    isConnected = false;
                }
            }
            catch (Exception e)
            {
                Console.WriteLine("关闭串口时发生异常:" + e.StackTrace);
            }
        }

        private void InitTimer()
        {
            heartBeatTimer = new System.Timers.Timer(Config.PLC_HEARTBEAT_INTEVAL);
            heartBeatTimer.Elapsed += new System.Timers.ElapsedEventHandler(OnTimerHeartBeat);
            heartBeatTimer.AutoReset = true;
            heartBeatTimer.Enabled = false;
            heartBeatTimer.Stop();
        }

        /// <summary>
        /// 开启心跳
        /// </summary>监测
        public void WatchHeartBeat()
        {
            heartBeatEnabled = true;
            heartBeatTimer.Enabled = true;
            heartBeatTimer.Start();
        }

        public void UnWatchHeartBeat()
        {
            heartBeatEnabled = false;
            heartBeatTimer.Stop();
            heartBeatTimer.Enabled = false;
        }

        /// <summary>
        /// PLC心跳监测
        /// </summary>
        /// <param name="source"></param>
        /// <param name="e"></param>
        private void OnTimerHeartBeat(object source, System.Timers.ElapsedEventArgs e)
        {
            if (!heartBeatEnabled) return;
            var isOK = CheckPLC();
            Console.WriteLine("PLC心跳监测:" + isOK);
            if (heartBeatDelegate != null)
            {
                heartBeatDelegate.Invoke(isOK);
            }
        }

        private void Connect(Action complete = null)
        {
            if (isConnected)
            {
                if (this.PLCInitCompleteDelegate != null)
                {
                    this.PLCInitCompleteDelegate.Invoke();
                }
                return;
            }

            ThreadHelper.ExcuteThreadTask(() =>
            {
                try
                {
                    InitTimer();
                    upper = new UpperComputerUtil();
                    upper.OpenSerialPort(Config.PLC_COM, 9600, 7, System.IO.Ports.StopBits.One, System.IO.Ports.Parity.Even);
                    ThreadHelper.Sleep(500);
                    if (!CheckPLC())
                    {
                        isConnected = false;
                        Console.WriteLine("PLC连接失败，再次尝试重连");
                        ThreadHelper.Sleep(500);
                        //再次重新连接PLC
                        Connect(complete);
                    }
                    else
                    {
                        isConnected = true;
                        Console.WriteLine("PLC已连接");
                        if (this.PLCInitCompleteDelegate != null)
                        {
                            this.PLCInitCompleteDelegate.Invoke();
                        }
                    }
                }

                catch (Exception ex)
                {
                    Console.WriteLine("PLC连接异常,{0} {1}", ex.Message, ex.StackTrace);
                    Logger.Write(Level.ERROR, "启动电机异常", ex);
                }
            });
        }

        private bool CheckPLC()
        {
            //获取拍照按钮状态
            JObject stopJobject = upper.ReadBoolResults("M70");

            if (stopJobject == null)
                return false;
            if (stopJobject.GetValue("Code").ToString().Equals("500"))
            {
                return false;
            }
            return true;
        }

        /// <summary>
        /// 读取当前xyz坐标点位置
        /// </summary>
        /// <returns></returns>
        public int[] readCurrentXYZ()
        {
            int x = -99999;
            int y = -99999;
            int z = -99999;
            int zIlluminant = -99999;

            JObject xPoint = upper.ReadResultsShort("D34");
            if (xPoint == null || xPoint.GetValue("Code").ToString().Equals("500"))
            {
                string msg = "读取X轴绝对位置,发生异常：" + xPoint.GetValue("msg").ToString();
                Console.WriteLine(msg);
                throw new Exception(msg);
            }
            else
            {
                x = (int)short.Parse(xPoint.GetValue("msg").ToString());
            }

            JObject yPoint = upper.ReadResultsShort("D35");
            if (yPoint == null || yPoint.GetValue("Code").ToString().Equals("500"))
            {
                string msg = "读取Y轴绝对位置,发生异常：" + yPoint.GetValue("msg").ToString();
                Console.WriteLine(msg);
                throw new Exception(msg);
            }
            else
            {
                y = (int)short.Parse(yPoint.GetValue("msg").ToString());
            }
            JObject zPoint = upper.ReadResultsShort("D36");
            if (zPoint == null || zPoint.GetValue("Code").ToString().Equals("500"))
            {
                string msg = "读取Z轴绝对位置,发生异常：" + zPoint.GetValue("msg").ToString();
                Console.WriteLine(msg);
                throw new Exception(msg);
            }
            else
            {
                z = (int)short.Parse(zPoint.GetValue("msg").ToString());
            }
            //读取光源轴的距离
            JObject zIlluminantPoint = upper.ReadResultsShort("D37");
            if (zIlluminantPoint == null || zIlluminantPoint.GetValue("Code").ToString().Equals("500"))
            {
                string msg = "读取Z轴绝对位置,发生异常：" + zIlluminantPoint.GetValue("msg").ToString();
                Console.WriteLine(msg);
                throw new Exception(msg);
            }
            else
            {
                zIlluminant = (int)short.Parse(zIlluminantPoint.GetValue("msg").ToString());
            }

            return new int[] { x, y, z,zIlluminant };
        }

        /// <summary>
        /// 记录上一次的X位置，避免无用的指令消耗时间
        /// </summary>
        private Int32 prevX = 0;

        /// <summary>
        /// 记录上一次的Y位置，避免无用的指令消耗时间
        /// </summary>
        private Int32 prevY = 0;

        /// <summary>
        /// 记录上一次的Z位置，避免无用的指令消耗时间
        /// </summary>
        private Int32 prevZ = 0;
        /// <summary>
        /// 记录上一次的光源轴的位置，避免无用的指令消耗时间
        /// </summary>
        private Int32 prevZIlluminant = 0;

        public void moveToXYZandCapture(Int32 x, Int32 y, Int32 z, bool captureEnable = true) {
           this.moveToXYZandCapture( x,  y,  z,  0,  captureEnable );
        }
        /// <summary>
        /// 移动到指定位置并拍照
        /// </summary>
        public void moveToXYZandCapture(Int32 x, Int32 y, Int32 z,Int32 zIlluminant, bool captureEnable = true)
        {
            try
            {
                if (checklimitStoped()) return;
                if (z> Config.CAMERA_FOCUS_DISTANCE_MAX) {
                    z = Config.CAMERA_FOCUS_DISTANCE_MAX;
                    Console.WriteLine("移动到指定位置，z轴距离大于了最大值：{0},当前值：{1}" , Config.CAMERA_FOCUS_DISTANCE_MAX,z);
                }

                bool xMoved = x != prevX;
                if (true || xMoved)
                {
                    Console.WriteLine("设置X轴距离,进行中....期望调节到：" + x);
                    JObject D20Result = upper.SendMsgInt("D9", x);//设置绝对距离（这个时候还不会动，要等下面M104命令执行）
                    if (D20Result.GetValue("Code").ToString().Equals("500"))
                    {
                        Console.WriteLine("设置X轴距离失败,D9报错：" + D20Result.GetValue("msg").ToString());
                        MessageBox.Show("设置X轴距离失败，报错" + D20Result.GetValue("msg").ToString());
                        return;
                    }
                    prevX = x;
                    Console.WriteLine("设置X轴距离,成功");
                }

                bool yMoved = y != prevY;
                if (true || yMoved)
                {
                    Console.WriteLine("设置Y轴距离,进行中....期望调节到：" + y);
                    JObject D20Result = upper.SendMsgInt("D10", y);//设置绝对距离（这个时候还不会动，要等下面M104命令执行）
                    if (D20Result.GetValue("Code").ToString().Equals("500"))
                    {
                        Console.WriteLine("设置Y轴距离失败,D10报错：" + D20Result.GetValue("msg").ToString());
                        MessageBox.Show("设置Y轴距离失败，报错" + D20Result.GetValue("msg").ToString());
                        return;
                    }
                    prevY = y;
                    Console.WriteLine("设置Y轴距离,成功");
                }

                bool zMoved = z != prevZ;
                if (true || zMoved)
                {
                    Console.WriteLine("设置Z轴距离,进行中....期望调节到：" + z);
                    JObject D20Result = upper.SendMsgInt("D11", z);//设置绝对距离（这个时候还不会动，要等下面M104命令执行）
                    if (D20Result.GetValue("Code").ToString().Equals("500"))
                    {
                        Console.WriteLine("设置Z轴距离失败,D11报错：" + D20Result.GetValue("msg").ToString());
                        MessageBox.Show("设置Z轴距离失败，报错" + D20Result.GetValue("msg").ToString());
                        return;
                    }
                    prevZ = z;
                    Console.WriteLine("设置Z轴距离,成功");
                }
                bool zIllMoved = zIlluminant != prevZIlluminant;
                if (true || zIllMoved) 
                {
                    Console.WriteLine("设置光源轴距离,进行中....期望调节到：" + zIlluminant);
                    JObject D43Result = upper.SendMsgInt("D43", zIlluminant);//设置绝对距离（这个时候还不会动，要等下面M104命令执行）
                    if (D43Result.GetValue("Code").ToString().Equals("500"))
                    {
                        Console.WriteLine("设置光源轴距离失败,D43报错：" + D43Result.GetValue("msg").ToString());
                        MessageBox.Show("设置光源轴距离失败，报错" + D43Result.GetValue("msg").ToString());
                        return;
                    }
                    prevZIlluminant = zIlluminant;
                 /*   JObject zIlluminantPoint = upper.ReadResultsShort("D37");
                    Console.WriteLine("读取光源轴目标位置======================================= ：" + zIlluminantPoint.GetValue("msg").ToString());*/
                }

                if (true)
                {
                    JObject M26Result = upper.SendMsgBoolean(captureEnable ? "M102" : "M104", true);//开始移动,M102会拍照，M104不会拍照
                    if (M26Result.GetValue("Code").ToString().Equals("500"))
                    {
                        Console.WriteLine("移动xyz轴到指定距离失败,M102报错：" + M26Result.GetValue("msg").ToString());
                        MessageBox.Show("移动xyz轴到指定距离失败，报错" + M26Result.GetValue("msg").ToString());
                        return;
                    }
                    else
                    {
                        bool stoped = false;
                        int maxTime = Math.Max(Math.Max(Math.Max(x, y), z) / 20, 20);//默认允许检查10次
                        Console.WriteLine("移动XYZ轴命令发送完成，等待检查移动XYZ轴是否停稳...maxTime {0}", maxTime);
                        Console.WriteLine("移动XYZ轴命令发送完成，X:{0},Y：{1}, Z:{2}, ", x,y,z);
                        int checkStopTimes = 0;
                        string checkErrorMsg = "";
                        while (!stoped && !AutoCaptrueHandler.stoping)
                        {
                            if (checkStopTimes > maxTime)
                            {
                                Console.WriteLine("检查移动xyz轴停稳失败，超过了最大检查次数");
                                MessageBox.Show("移动xyz轴到指定距离失败，超过了最大检查次数");
                                break;
                            }

                            //检查达到了临界点
                            if (this.checklimitStoped()) {
                                break;
                            }

                            try
                            {
                                Thread.Sleep(100);
                                //检查是否已经移动到目标位置
                                JObject checkResult = upper.ReadBoolResults("M122");
                               
                                if (checkResult.GetValue("Code").ToString().Equals("0"))
                                {
                                    var attachTarget = bool.Parse(checkResult.GetValue("msg").ToString());
                                    Console.WriteLine("检查是否已经移动到目标位置 M122命令的返回值： {0}", checkResult.GetValue("msg").ToString());
                                    if (attachTarget)
                                    {
                                        stoped = true;
                                        Console.WriteLine("检查移动xyz轴停稳-成功!");
                                        break;
                                    }
                                    else
                                    {
                                        Console.WriteLine("...检查移动xyz轴停稳，还未到达目标...当前值：" + attachTarget);
                                    }
                                }
                                else
                                {
                                    checkErrorMsg = checkResult.GetValue("msg").ToString();
                                    Console.WriteLine("检查移动xyz轴停稳，报错：" + checkResult.GetValue("msg").ToString());
                                    MessageBox.Show("检查移动xyz轴停稳，报错:" + checkErrorMsg);
                                }
                            }
                            catch (Exception ex)
                            {
                                Console.WriteLine("移动xyz轴失败,{0} {1}", ex.Message, ex.StackTrace);
                                MessageBox.Show("移动xyz轴失败，报错" + ex.Message);
                                return;
                            }
                            finally
                            {
                                checkStopTimes++;
                            }
                        }
                    }
                }
                else
                {
                    Console.WriteLine("由于xyz都没有什么变化，所有电机都没有移动");
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine("移动xyz轴失败,{0} {1}", ex.Message, ex.StackTrace);
                MessageBox.Show("移动xyz轴失败，报错" + ex.Message);
                return;
            }
            finally
            {
            }
        }

        bool focusDistanceChanged = false;
        /// <summary>
        /// 调节焦距
        /// （调节Z轴的位置）
        /// </summary>
        public void ChangeFocusDistance(int distance, Action<int, string> completeCallback)
        {
            if (checklimitStoped()) return; 

            Console.WriteLine("调节焦距目标：" + distance);
            /* if (!backedToZero)
             {
                 Console.WriteLine("Z轴还未回到原点，无法继续调节");
                 if (completeCallback != null) completeCallback(501, "Z轴还未回到原点，无法继续调节");
                 return;
             }*/

            if (distance > Config.CAMERA_FOCUS_DISTANCE_MAX)
            {
                Console.WriteLine("调节焦距失败，距离不能大于"+ Config.CAMERA_FOCUS_DISTANCE_MAX);
                if (completeCallback != null) completeCallback(502, "调节焦距失败，距离不能大于" + Config.CAMERA_FOCUS_DISTANCE_MAX);
                return;
            }

            if (focusDistanceChanged)
            {
                Console.WriteLine("调节焦距失败，前一个调节任务正在执行中");
                if (completeCallback != null) completeCallback(503, "调节焦距失败，前一个调节任务正在执行中");
                return;
            }

            try
            {
                focusDistanceChanged = true;
                Console.WriteLine("调节焦距,进行中....期望调节到：" + distance);
                JObject D20Result = upper.SendMsgInt("D8", distance);//设置绝对距离（这个时候还不会动，要等下面M26命令执行）
                if (D20Result.GetValue("Code").ToString().Equals("500"))
                {
                    Console.WriteLine("调节焦距失败,D20报错：" + D20Result.GetValue("msg").ToString());
                    if (completeCallback != null) completeCallback(500, "调节焦距时设置距离报错：" + D20Result.GetValue("msg").ToString());
                    return;
                }
                else
                {
                    JObject M26Result = upper.SendMsgBoolean("M8", true);//开始移动
                    if (M26Result.GetValue("Code").ToString().Equals("500"))
                    {
                        Console.WriteLine("调节焦距失败,M26报错：" + M26Result.GetValue("msg").ToString());
                        if (completeCallback != null) completeCallback(500, "调节焦距时报错：" + M26Result.GetValue("msg").ToString());
                        return;
                    }
                    else
                    {
                        Console.WriteLine("调节焦距命令发送完成，等待检查调焦是否停稳...");
                        //TODO 如果想知道有没有停稳 ，查询D8360
                        bool stoped = false;
                        int maxTime = distance / 100;
                        int checkStopTimes = 0;
                        string checkErrorMsg = "";
                        while (!stoped)
                        {
                            if (checkStopTimes > maxTime)
                            {
                                Console.WriteLine("检查调焦停稳失败，超过了最大检查次数");
                                if (completeCallback != null) completeCallback(500, "检查调焦停稳失败，超过了最大检查次数,最后一次检查时报错：" + checkErrorMsg);
                                break;
                            }

                            //检查达到了临界点
                            if (this.checklimitStoped())
                            {
                                break;
                            }

                            try
                            {
                                Thread.Sleep(100);
                                //检查是否已经移动到目标位置
                                JObject checkResult = upper.ReadBoolResults("M25");
                                if (checkResult.GetValue("Code").ToString().Equals("0"))
                                {
                                    var attachTarget = bool.Parse(checkResult.GetValue("msg").ToString());
                                    if (attachTarget)
                                    {
                                        stoped = true;
                                        Console.WriteLine("检查调焦停稳-成功!");
                                        upper.SendMsgBoolean("M25", false);
                                        if (completeCallback != null) completeCallback(0, "检查调焦停稳-成功");
                                        break;
                                    }
                                    else
                                    {
                                        Console.WriteLine("...检查调焦停稳，还未到达目标...当前值：" + attachTarget);
                                    }
                                }
                                else
                                {
                                    checkErrorMsg = checkResult.GetValue("msg").ToString();
                                    Console.WriteLine("检查调焦停稳，报错：" + checkResult.GetValue("msg").ToString());
                                }
                            }
                            catch (Exception ex)
                            {
                                Console.WriteLine("调节焦距失败,{0} {1}", ex.Message, ex.StackTrace);
                                if (completeCallback != null) completeCallback(500, "调节焦距发生异常：" + ex.Message);
                                return;
                            }
                            finally
                            {
                                checkStopTimes++;
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine("调节焦距失败,{0} {1}", ex.Message, ex.StackTrace);
                if (completeCallback != null) completeCallback(500, "调节焦距发生异常：" + ex.Message);
                return;
            }
            finally
            {
                focusDistanceChanged = false;
            }

            if (completeCallback != null) completeCallback(0, "调节成功!");
        }

        bool limitStoped = false;
        /// <summary>
        /// 检查电机是否达到临界点停止了
        /// </summary>
        /// <returns></returns>
        public bool checklimitStoped() {
          /*  if (limitStoped) return true;
            var stoped = false;
            string limitMsg = "";
            //X限位
            JObject x10 = upper.ReadBoolResults("X10");
            JObject x2 = upper.ReadBoolResults("X2");
            var xLeftLimit=bool.Parse(x10.GetValue("msg").ToString());
            var xRightLimit = bool.Parse(x2.GetValue("msg").ToString());
            if (xLeftLimit || xRightLimit)
            {
                stoped = true;
                limitMsg = limitMsg + "X";
            }
            //Y限位
            JObject x13 = upper.ReadBoolResults("X13");
            JObject x15 = upper.ReadBoolResults("X15");
            var yLeftLimit = bool.Parse(x13.GetValue("msg").ToString());
            var yRightLimit = bool.Parse(x15.GetValue("msg").ToString());
            if (yLeftLimit || yRightLimit)
            {
                stoped = true;
                limitMsg = limitMsg + "Y";
            }
            //Z限位
            JObject x16 = upper.ReadBoolResults("X16");
            JObject x20 = upper.ReadBoolResults("X20");
            var zLeftLimit = bool.Parse(x16.GetValue("msg").ToString());
            var zRightLimit = bool.Parse(x20.GetValue("msg").ToString());
            if (zLeftLimit || zRightLimit) { 
                stoped = true;
                limitMsg = limitMsg + "Z";
                JObject D138 = upper.ReadResultsShort("-+" +
                    "");
                JObject D139 = upper.ReadResultsShort("D139");
                Console.WriteLine("================================》zLeftLimit:{0},   zRightLimit:{1}", x16.GetValue("msg").ToString(), x20.GetValue("msg").ToString());
                Console.WriteLine("================================》Z轴正限D138:{0},  D139:{1}", this.getLimitPoint(D138), this.getLimitPoint(D139));
            }
          
            if (stoped)
            {
                limitStoped = true;
                this.stopMoving();
                 string errorMsg = string.Format("{0}轴电机已超过量程，请摆正钉盒并转动手轮到正常区域", limitMsg);
              //  string errorMsg = string.Format("{0}轴电机已超过量程，移动到机械原点", limitMsg);
                //注意：这里必须要写这么多参数，不然弹出来的不在最前面，看不到。
                if (MessageBox.Show(errorMsg, "提示", MessageBoxButtons.OK, MessageBoxIcon.None, MessageBoxDefaultButton.Button1, MessageBoxOptions.DefaultDesktopOnly) == DialogResult.OK)
                {
                    limitStoped = false;
                   // this.moveToOrigin();
                };
            }
            return stoped;*/


            if (limitStoped) return true;
             var stoped = false;
             //this.getLimitLocation();
             JObject checkResult = upper.ReadBoolResults("M27");
             if (checkResult.GetValue("Code").ToString().Equals("0"))
             {
                 stoped = bool.Parse(checkResult.GetValue("msg").ToString());
                 Console.WriteLine("检查电机是否达到临界点,{0}", stoped.ToString());
                 if (stoped) {
                     limitStoped = true;
                     this.stopMoving();
                     //注意：这里必须要写这么多参数，不然弹出来的不在最前面，看不到。
                     if (MessageBox.Show("电机已超过量程，请摆正钉盒并转动手轮到正常区域", "提示", MessageBoxButtons.OK, MessageBoxIcon.None, MessageBoxDefaultButton.Button1, MessageBoxOptions.DefaultDesktopOnly) == DialogResult.OK) {
                         limitStoped = false;
                     };
                 }
             }
             else
             {
                 Console.WriteLine("检查电机是否达到临界点，报错：" + checkResult.GetValue("msg").ToString());
             }
             return stoped;
        }
        private int getLimitPoint(JObject checkResult) {
            if (checkResult.GetValue("Code").ToString().Equals("0"))
            {
                return int.Parse(checkResult.GetValue("msg").ToString());
            }
            else {
                Console.WriteLine("检查电机是否达到临界点，报错：" + checkResult.GetValue("msg").ToString());
            }
            return -99999;
        }

        /// <summary>
        /// 让所有电机都停止移动
        /// </summary>
        public void stopMoving()
        {
            JObject stopJobject = upper.SendMsgBoolean("M199", true);
            if (stopJobject == null || stopJobject.GetValue("Code").ToString().Equals("500"))
            {
                Console.WriteLine("所有电机停止移动,发生异常：" + stopJobject.GetValue("msg").ToString());
                MessageBox.Show("所有电机停止移动发生异常，请联系管理员");
                return;
            }
            Console.WriteLine("所有电机停止移动-成功");
        }

        bool backedToZero = false;

        /// <summary>
        /// 让Z轴回到机械原点
        /// </summary>
        public void backToZero()
        {
            //发送回到原点的指令
            Console.WriteLine("Z轴回到原点,进行中....");
            JObject commandResult = upper.SendMsgBoolean("M20", true);
            if (commandResult.GetValue("Code").ToString().Equals("500"))
            {
                MessageBox.Show("让Z轴回到原点失败");
                Console.WriteLine("让Z轴回到原点失败，报错：" + commandResult.GetValue("msg").ToString());
            }
            else
            {
                while (!backedToZero)
                {
                    Thread.Sleep(500);
                    //检查是否已经回到了原点
                    JObject checkResult = upper.ReadBoolResults("M24");
                    if (checkResult.GetValue("Code").ToString().Equals("0"))
                    {
                        if (Boolean.Parse(checkResult.GetValue("msg").ToString()))
                        {
                            backedToZero = true;
                            Console.WriteLine("检查Z轴回到原点-成功!");
                            if (z2ZeroDelegate != null)
                            {
                                z2ZeroDelegate.Invoke();
                            }
                        }
                        else
                        {
                            Console.WriteLine("...检查到Z轴还未回到原点...");
                        }
                    }
                    else
                    {
                        Console.WriteLine("检查Z轴回到原点失败，报错：" + checkResult.GetValue("msg").ToString());
                    }
                }
            }
        }

        /// <summary>
        /// 检查是否回到了原点
        /// </summary>
        /// <returns></returns>
        public bool checkOrigin()
        {
            //检查是否已经移动到目标位置
            JObject checkResult = upper.ReadBoolResults("M126");
            if (checkResult.GetValue("Code").ToString().Equals("0"))
            {
                var attachTarget = bool.Parse(checkResult.GetValue("msg").ToString());
                if (attachTarget)
                {
                    backedToZero = true;
                    Console.WriteLine("检查是否回到了原点-成功!");
                }
            }
            else
            {
                Console.WriteLine("检查是否回到了原点，报错：" + checkResult.GetValue("msg").ToString());
            }
            return backedToZero;
        }

        /// <summary>
        /// 移动到机械原点
        /// </summary>
        public void moveToOrigin()
        {
           
                JObject stopJobject = upper.SendMsgBoolean("M106", true);
                if (stopJobject == null || stopJobject.GetValue("Code").ToString().Equals("500"))
                {
                    Console.WriteLine("回到原点,发生异常：" + stopJobject.GetValue("msg").ToString());
                    MessageBox.Show("回到机械原点发生异常，请联系管理员");
                    return;
                }

                Console.WriteLine("回到机械原点命令发送完成，等待检查是否停稳...");
                bool stoped = false;
                int maxTime = 300;
                int checkStopTimes = 0;
                string checkErrorMsg = "";
                while (!stoped)
                {
                    if (checkStopTimes > maxTime)
                    {
                        Console.WriteLine("检查回到机械原点停稳失败，超过了最大检查次数");
                        //if (completeCallback != null) completeCallback(500, "检查调焦停稳失败，超过了最大检查次数,最后一次检查时报错：" + checkErrorMsg);
                        break;
                    }
                    try
                    {
                        Thread.Sleep(100);
                        //检查是否已经移动到目标位置
                        JObject checkResult = upper.ReadBoolResults("M126");
                        if (checkResult.GetValue("Code").ToString().Equals("0"))
                        {
                            var attachTarget = bool.Parse(checkResult.GetValue("msg").ToString());
                            if (attachTarget)
                            {
                                backedToZero = true;
                                stoped = true;
                                Console.WriteLine("检查回到机械原点停稳-成功!");
                                //if (completeCallback != null) completeCallback(0, "检查调焦停稳-成功");
                                break;
                            }
                            else
                            {
                                Console.WriteLine("...检查回到机械原点停稳，还未到达目标...当前值：" + attachTarget);
                            }
                        }
                        else
                        {
                            checkErrorMsg = checkResult.GetValue("msg").ToString();
                            Console.WriteLine("检查回到机械原点停稳，报错：" + checkResult.GetValue("msg").ToString());
                        }
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine("回到机械原点失败,{0} {1}", ex.Message, ex.StackTrace);
                        //if (completeCallback != null) completeCallback(500, "回到机械原点发生异常：" + ex.Message);
                        return;
                    }
                    finally
                    {
                        checkStopTimes++;
                    }
                }

                if (this.moveToOriginCompleteDelegate != null)
                {
                    this.moveToOriginCompleteDelegate.Invoke();
                }
        }

        /// <summary>
        /// 检查抓拍按钮是否按下
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        public bool checkCapturePressed()
        {
            try
            {
                if (upper == null || !isConnected) return false;
                
                JObject stopJobject = upper.ReadBoolResults("M70");
                if (stopJobject == null || stopJobject.GetValue("Code").ToString().Equals("500"))
                {
                    Console.WriteLine("无法监测到拍照按钮状态," + stopJobject.GetValue("msg"));
                    return false;
                }

                bool status = bool.Parse(stopJobject.GetValue("msg").ToString());
                //Console.WriteLine("Capture_Elapsed 按钮状态" + status.ToString());
                return status;
            }
            catch (Exception ex)
            {
                Console.WriteLine("抓拍，发生异常：" + ex.StackTrace);
                MessageBox.Show("抓拍发生异常，请找管理员");
            }
            finally
            {
            }
            return false;
        }

        /// <summary>
        /// 锁定手动调整手轮
        /// </summary>
        public void lockManual()
        {
            JObject stopJobject = upper.SendMsgBoolean("M108", true);
            if (stopJobject == null || stopJobject.GetValue("Code").ToString().Equals("500"))
            {
                Console.WriteLine("所有电机停止移动,发生异常：" + stopJobject.GetValue("msg").ToString());
                MessageBox.Show("所有电机停止移动发生异常，请联系管理员");
                return;
            }
            Console.WriteLine("所有电机停止移动-成功");
        }

        /// <summary>
        /// 解锁手动调整手轮
        /// </summary>
        public void unlockManual()
        {
            JObject stopJobject = upper.SendMsgBoolean("M108", false);
            if (stopJobject == null || stopJobject.GetValue("Code").ToString().Equals("500"))
            {
                Console.WriteLine("所有电机停止移动,发生异常：" + stopJobject.GetValue("msg").ToString());
                MessageBox.Show("所有电机停止移动发生异常，请联系管理员");
                return;
            }
            Console.WriteLine("所有电机停止移动-成功");
        }

        /// <summary>
        /// 改变电机的速度
        /// </summary>
        /// <param name="x"></param>
        /// <param name="y"></param>
        /// <param name="z"></param>
        public void ChangeSpeed(int x,int y,int z) {
            if (x > 0) {
                upper.SendMsgInt("D0",x);
            }
            if (y > 0)
            {
                upper.SendMsgInt("D1", y);
            }
            if (z > 0)
            {
                upper.SendMsgInt("D2", z);
                //光源轴移动速度
                upper.SendMsgInt("D41", 1200);
            }
        
        }
        /// <summary>
        /// 获取极限位置
        /// 
        /// </summary>
        public void getLimitLocation() {
            //X限位
            JObject D134 = upper.ReadResults("D134");
            JObject D135 = upper.ReadResults("D135");
            //Z限位
            JObject d138 = upper.ReadResultsShort("D138");
            JObject d139 = upper.ReadResultsShort("D139");
            //Z 当前位置
            JObject d36 = upper.ReadResultsShort("d36");
            //XYZ 当前位置
            int[] xyz = readCurrentXYZ();
            Console.WriteLine("444444444444444");
        }
    }
}
